/**
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to marcus@lateralminds.com.au so I can send you a copy immediately.
 *
 * @copyright  Copyright (c) 2008 Lateral Minds (http://www.lateralminds.com.au)
 * @version    $Id$
 * @license    New BSD License
 */

package com.lateralminds.alfresco.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.namespace.QName;

/**
 * A utility service that can be used to abstract some bloody painful and
 * repetitive alfresco services. It covers a range of things, so "Lateral" kinda
 * fits as a name... no really, it does!
 * 
 * To use this, add the following configuration to your nearest spring config
 * 
 * @author Marcus Nyeholt
 * 
 */
public interface LateralService
{
    /**
     * Get the working copy for a given document
     * 
     * @param nodeRef
     * @return
     */
    public NodeRef getWorkingCopy(NodeRef nodeRef);
    
    /**
     * Get the company home noderef
     * @return
     */
    public NodeRef getCompanyHome();

    /**
     * Get a result set for a given lucene search term.
     * 
     * @param searchString
     * @param searchSvc
     * @return
     */
    public ResultSet search(String searchString);

    /**
     * Get a noderef for the given alfresco path value
     * 
     * @param path
     * @return
     */
    public  NodeRef getRefByPath(String path);
    
    /**
     * Get a result set for a lucene search
     * 
     * @param searchString
     * @param sortBy
     * @param asc
     * @return
     */
    public ResultSet search(String searchString, String sortBy, Boolean asc);

    /**
     * Perform a lucene search and get back a list of noderefs
     * 
     * @param searchString
     * @return
     */
    public List<NodeRef> searchForNodeRefs(String searchString);

    /**
     * Perform a search and get back a list of noderefs.
     * 
     * @param searchString
     * @param sortBy
     * @param asc
     * @return
     */
    public List<NodeRef> searchForNodeRefs(String searchString, String sortBy,
            Boolean asc);

    /**
     * Set the content for a given node.
     * 
     * @param node
     * @param content
     * @param svc
     */
    public void setNodeContent(NodeRef node, String content, String mimeType);

    /**
     * Set the content of a given node. 
     * 
     * @param node
     * @param content
     * @param mimeType
     * @param property
     */
    public void setNodeContent(NodeRef node, String content, String mimeType, QName property);
    
    /**
     * Set the content of a given node. 
     * 
     * @param node
     * @param content
     * @param mimeType
     * @param property
     */
    public void setNodeContent(NodeRef node, InputStream content, String mimeType, QName property);
    
    /**
     * Set the content for a given node.
     * 
     * @param node
     * @param content
     * @param svc
     */
    public void setNodeContent(NodeRef node, InputStream content,
            String mimeType);

    /**
     * Get the content for a given noderef.
     * 
     * @param nodeRef
     * @return
     */
    public String getNodeContent(NodeRef nodeRef);
    
    /**
     * Get the content for a given noderef's property
     * @param nodeRef
     * @param property
     * @return
     */
    public String getNodeContent(NodeRef nodeRef, QName property);

    /**
     * Get the mimetype for a given filename
     * 
     * @param filename
     * @param mimetypeService
     */
    public String getMimetypeFor(String filename);

    /**
     * Indicates whether the given noderef is an image or not
     * 
     * @param ref
     * @return
     */
    public boolean isImage(NodeRef ref);
    
    /**
     * Get the name for a given noderef.
     * 
     * @param n
     * @param ns
     * @return
     */
    public String refName(NodeRef n);

    /**
     * Get the title for a noderef, returning the name if the title is null
     * 
     * @param n
     * @param ns
     * @return
     */
    public String refTitle(NodeRef n);

    /**
     * Cleans the uploaded filename to just the document name (as IE sends the
     * full path name...)
     * 
     * @param uploadName
     * @return
     */
    public String cleanFileUploadName(String uploadName);

    /**
     * Recursively empties a directory, leaving it intact once complete
     * @param path
     * @return
     */
    public boolean emptyDirectory(File path);
    
    /**
     * Retrieves the child of the given parent node. If the child doesn't
     * exist, create it
     * 
     * @param parent
     * @param name
     * @param type
     * @return the existing noderef, or the newly created one
     */
    public NodeRef retrieveChildNode(NodeRef parent, String name, QName type);
    
    /**
     * Utility method to create a node with the parameters specified.
     * Checks for existing child node of the parent with the same name 
     * as that specified. If it exists, this method will throw an 
     * {@link IllegalArgumentException}. 
     * 
     * @param parent
     *            The parent of the node to be created.
     * @param name
     *            The cm:name of the node to be created.
     * @param assocType
     *            The association type between the node and the parent.
     * @param type
     *            The type of the node.
     * @param content
     *            The content to store in the node.
     * @param mimeType
     *            The mimetype of the content.
     * @param props
     *            The properties to assign.
     * @return {@link NodeRef} of the node created.
     * @throws IllegalArgumentException if the parent already has a child node with
     * the name specified.
     */
    public NodeRef createNode(NodeRef parent, String name,
            QName assocType, QName type, byte[] content, String mimeType,
            Map<QName, Serializable> props);

    /**
     * Gets the list of documents that were associated to the passed
     * in noderef at the given version label. If there was no versionable aspect 
     * applied to the noderef, we'll just return all its current associations (ie
     * the current version). 
     * 
     * @param ref The noderef to get the associated version noderefs for
     * @param versionLabel The version label to get the noderefs at
     * @param associations The list of association refs to
     * @return the list of noderefs
     */
    public List<NodeRef> getAssociatedNodeRefsAtVersion(NodeRef ref, String versionLabel, List<AssociationRef> associations);
    
    /**
     * Get the {@link InputStream} for a piece of content.
     * @param nodeRef The {@link NodeRef} for this content.
     * @return InputStream
     */
    public InputStream getContentInputStream(NodeRef nodeRef);
    
    /**
     * Get the {@link InputStream} for a piece of content.
     * @param nodeRef The {@link NodeRef} for this content.
     * @param property The property to retrieve the content from.
     * @return InputStream
     */
    public InputStream getContentInputStream(NodeRef nodeRef, QName property);
    
    /**
     * Write the node to a file on the local filesystem
     * 
     * @param aNodeRef
     * @param outFile
     * @return 
     */
    public void writeNodeToFile(NodeRef aNodeRef, File outFile) throws IOException;
    
    /**
     * import a file system file into an Alfresco Space
     * 
     * @param file
     * @param targetSpaceRef
     * @throws IOException 
     */
    public NodeRef importFile(File file, NodeRef targetSpaceRef) throws IOException;
    
    /**
     * import a file system directory into an Alfresco Space
     * convenience method uses defaults for node type, name and title
     * @param dir
     * @param targetSpaceRef
     */
    public NodeRef importDirectory(File dir, NodeRef targetSpaceRef) throws IOException;

    /**
     * import a filesystem directory into an Alfresco Space
     * 
     * @param dir the directory to import
     * @param targetSpaceRef the nodeRef where to import it to
     * @param nodeType the desired folder type to use, defaults to cm:folder
     * @param name a node name, defaults to the directory name
     * @param title, a node title, defaults to the name
     * @return
     * @throws IOException
     */
    public NodeRef importDirectory(File dir, NodeRef targetSpaceRef, QName nodeType, String name, String title) throws IOException;

    /**
     * convenience method for byte copying streams
     * 
     * @param in
     * @param fileOutputStream
     */
    public void copy(InputStream in, OutputStream outputStream) throws IOException;

    /**
     * convenience method for byte copying a binary file 
     * 
     * @param src
     * @param dst
     * @throws IOException
     */
    public void copyFile(File src, File dst) throws IOException;
}
